package com.ncmem.up6.sql;

import com.ncmem.up6.utils.ConfigReader;
import com.ncmem.up6.utils.DataBaseType;
import org.apache.commons.lang.StringUtils;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class SqlParam {
	public String m_name="";
	public boolean m_valBool = false;
	public byte m_valByte=0;
	public String m_valStr="";
	public int m_valInt=0;
	public short m_valShort=0;
	public long m_valLong=0;
	public Date m_valTm=new Date();
	public String m_namePre="@";
	public String pre = "=";
	public int length = 0;
	public boolean primary = false;//是否主键
	public boolean identity = false;//是否自增键
	protected String m_type;//字段类型,string,int,bool
	public DataBaseType m_dbType= DataBaseType.SqlServer;

	public String getParamterName() { return this.m_namePre+this.m_name; }
	public Object getValue(){
		if(StringUtils.equalsIgnoreCase("string",this.m_type)) return this.m_valStr;
		else if(StringUtils.equalsIgnoreCase("int",this.m_type)) return this.m_valInt;
		else if(StringUtils.equalsIgnoreCase("datetime",this.m_type)) return this.m_valTm;
		else if(StringUtils.equalsIgnoreCase("long",this.m_type)) return this.m_valLong;
		else if(StringUtils.equalsIgnoreCase("smallint",this.m_type)) return this.m_valInt;
		else if(StringUtils.equalsIgnoreCase("tinyint",this.m_type)) return this.m_valInt;
		else if(StringUtils.equalsIgnoreCase("short",this.m_type)) return this.m_valShort;
		else if(StringUtils.equalsIgnoreCase("byte",this.m_type)) return this.m_valByte;
		else if(StringUtils.equalsIgnoreCase("bool",this.m_type)) return this.m_valBool;
		return null;
	}
	public void setValue(Object v) throws ParseException {
		if(StringUtils.equalsIgnoreCase("string",this.m_type)) this.m_valStr=v.toString();
		else if(StringUtils.equalsIgnoreCase("int",this.m_type)) this.m_valInt = Integer.parseInt(v.toString());
		else if(StringUtils.equalsIgnoreCase("datetime",this.m_type)) this.m_valTm = (Date)v;
		else if(StringUtils.equalsIgnoreCase("long",this.m_type)) this.m_valLong = Long.parseLong(v.toString());
		else if(StringUtils.equalsIgnoreCase("smallint",this.m_type)) this.m_valInt = Integer.parseInt(v.toString());
		else if(StringUtils.equalsIgnoreCase("tinyint",this.m_type)) this.m_valInt = Integer.parseInt(v.toString());
		else if(StringUtils.equalsIgnoreCase("short",this.m_type)) this.m_valShort = Short.parseShort(v.toString());
		else if(StringUtils.equalsIgnoreCase("byte",this.m_type)) this.m_valByte = Byte.parseByte(v.toString());
		else if(StringUtils.equalsIgnoreCase("bool",this.m_type)) this.m_valBool = Boolean.parseBoolean(v.toString());
	}

	public SqlParam(){
	}
	public SqlParam(String name,byte v) {
		this.m_name=name;
		this.m_valByte = v;
	}
	
	public SqlParam(String name,Boolean v) {
		this.m_name=name;
		this.m_valBool = v;
		//oracle
		this.m_valInt = v?1:0;
	}
	
	public SqlParam(String name,String v)
	{
		this.m_name=name;
		this.m_valStr = v;		
	}
	
	public SqlParam(String name,short v)
	{
		this.m_name=name;
		this.m_valShort = v;
	}
	
	public SqlParam(String name,int v)
	{
		this.m_name=name;
		this.m_valInt = v;
	}
	
	public SqlParam(String name,long v)
	{
		this.m_name=name;
		this.m_valLong = v;
	}
	
	public SqlParam(String name,Date v)
	{
		this.m_name=name;
		this.m_valTm = v;
	}

	public SqlParam(String name,String v, String pre)
	{
		if (ConfigReader.dbType() == DataBaseType.Oracle)
			this.m_namePre = ":";
		this.m_name = name;
		this.m_valStr = v;
		this.m_type = "string";
		this.pre = pre;
	}
	public SqlParam(String name, byte v,String pre)
	{
		this.m_name = name;
		this.m_valByte = v;
		this.m_type = "byte";
		this.pre = pre;
	}
	public SqlParam(String name, Boolean v,String pre)
	{
		if (ConfigReader.dbType() == DataBaseType.Oracle)
			this.m_namePre = ":";
		this.m_name = name;
		this.m_valBool = v;
		//oracle
		this.m_valInt = v?1:0;
		this.m_type = "bool";
		this.pre = pre;
	}
	/**
	 *
	 * @param ps
	 * @param tmp string模板，%s
	 * @param separator 分隔符，,
	 * @return
	 */
	public static String mergeNames(SqlParam[] ps,String tmp,String separator){
		List<String> names = new ArrayList<String>();
		for(SqlParam p : ps){
			names.add(tmp.replaceAll("%s",p.m_name));
		}
		return StringUtils.join(names.toArray(),separator);
	}

	/**
	 *
	 * @param cmd
	 * @param i 参数索引，基于1
	 */
	public void bind(PreparedStatement cmd,int i) throws SQLException {
		if(StringUtils.equalsIgnoreCase("string", this.m_type)) cmd.setString(i, this.m_valStr );
		else if(StringUtils.equalsIgnoreCase("int", this.m_type)) cmd.setInt(i, this.m_valInt );
		else if(StringUtils.equalsIgnoreCase("datetime", this.m_type)) cmd.setTimestamp( i,new java.sql.Timestamp(this.m_valTm.getTime()) );
		else if(StringUtils.equalsIgnoreCase("long", this.m_type)) cmd.setLong( i, this.m_valLong );
		else if(StringUtils.equalsIgnoreCase("smallint", this.m_type)) cmd.setInt( i, this.m_valInt );
		else if(StringUtils.equalsIgnoreCase("tinyint", this.m_type)) cmd.setInt( i, this.m_valInt );
		else if(StringUtils.equalsIgnoreCase("short", this.m_type)) cmd.setShort( i, this.m_valShort );
		else if(StringUtils.equalsIgnoreCase("byte", this.m_type)) cmd.setByte( i, this.m_valByte );
		else if(StringUtils.equalsIgnoreCase("bool", this.m_type)) cmd.setBoolean(i, this.m_valBool);
	}

	public Object read(ResultSet r, int i) throws SQLException {
		if(StringUtils.equalsIgnoreCase("string", this.m_type)) {
			String v = r.getString(i);
			return v==null?"":v.trim();
		}
		else if(StringUtils.equalsIgnoreCase("int", this.m_type)) return r.getInt(i);
		else if(StringUtils.equalsIgnoreCase("datetime", this.m_type)) return new Date(r.getTimestamp( i).getTime());
		else if(StringUtils.equalsIgnoreCase("long", this.m_type)) return r.getLong( i);
		else if(StringUtils.equalsIgnoreCase("smallint", this.m_type)) return r.getInt( i);
		else if(StringUtils.equalsIgnoreCase("tinyint", this.m_type)) return r.getInt( i);
		else if(StringUtils.equalsIgnoreCase("short", this.m_type)) return r.getShort( i);
		else if(StringUtils.equalsIgnoreCase("byte", this.m_type)) return r.getByte( i);
		else if(StringUtils.equalsIgnoreCase("bool", this.m_type)) return r.getBoolean(i);
		return null;
	}

	public Object read(ResultSet r) throws SQLException {
		if(StringUtils.equalsIgnoreCase("string", this.m_type)) {
			String v = r.getString(this.m_name);
			return v==null?"":v.trim();
		}
		else if(StringUtils.equalsIgnoreCase("int", this.m_type)) return r.getInt(this.m_name);
		else if(StringUtils.equalsIgnoreCase("datetime", this.m_type)) return new Date(r.getTimestamp( this.m_name).getTime());
		else if(StringUtils.equalsIgnoreCase("long", this.m_type)) return r.getLong( this.m_name);
		else if(StringUtils.equalsIgnoreCase("smallint", this.m_type)) return r.getInt( this.m_name);
		else if(StringUtils.equalsIgnoreCase("tinyint", this.m_type)) return r.getInt( this.m_name);
		else if(StringUtils.equalsIgnoreCase("short", this.m_type)) return r.getShort( this.m_name);
		else if(StringUtils.equalsIgnoreCase("byte", this.m_type)) return r.getByte( this.m_name);
		else if(StringUtils.equalsIgnoreCase("bool", this.m_type)) return r.getBoolean(this.m_name);
		return null;
	}
}